package zy.service.money.income.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import zy.dao.approve.ApproveRecordDAO;
import zy.dao.base.shop.ShopDAO;
import zy.dao.money.bank.BankDAO;
import zy.dao.money.bank.BankRunDAO;
import zy.dao.money.income.IncomeDAO;
import zy.dao.sys.print.PrintDAO;
import zy.dto.money.income.IncomeReportDto;
import zy.entity.PageData;
import zy.entity.PageInfo;
import zy.entity.approve.T_Approve_Record;
import zy.entity.money.bank.T_Money_Bank;
import zy.entity.money.bank.T_Money_BankRun;
import zy.entity.money.income.T_Money_Income;
import zy.entity.money.income.T_Money_IncomeList;
import zy.entity.sys.user.T_Sys_User;
import zy.service.money.income.IncomeService;
import zy.util.CommonUtil;
import zy.util.DateUtil;
import zy.util.StringUtil;

@Service
public class IncomeServiceImpl implements IncomeService{
	@Resource
	private IncomeDAO incomeDAO;
	@Resource
	private ApproveRecordDAO approveRecordDAO;
	@Resource
	private BankDAO bankDAO;
	@Resource
	private BankRunDAO bankRunDAO;
	@Resource
	private ShopDAO shopDAO;
	@Resource
	private PrintDAO printDAO;
	
	@Override
	public PageData<T_Money_Income> page(Map<String, Object> params) {
		Integer pageSize = (Integer)params.get(CommonUtil.PAGESIZE);
		Integer pageIndex = (Integer)params.get(CommonUtil.PAGEINDEX);
		
		Integer totalCount = incomeDAO.count(params);
		PageInfo pageInfo = new PageInfo(totalCount, pageSize, pageIndex);
		params.put(CommonUtil.START, (pageIndex-1)*pageSize);
		params.put(CommonUtil.END, pageSize);
		
		List<T_Money_Income> list = incomeDAO.list(params);
		PageData<T_Money_Income> pageData = new PageData<T_Money_Income>();
		pageData.setPageInfo(pageInfo);
		pageData.setList(list);
		return pageData;
	}

	@Override
	public T_Money_Income load(Integer ic_id) {
		T_Money_Income income = incomeDAO.load(ic_id);
		if(income != null){
			T_Approve_Record approve_Record = approveRecordDAO.load(income.getIc_number(), income.getCompanyid());
			if(approve_Record != null){
				income.setAr_describe(approve_Record.getAr_describe());
			}
		}
		return income;
	}
	
	@Override
	public T_Money_Income load(String number,Integer companyid) {
		return incomeDAO.load(number, companyid);
	}
	
	@Override
	public List<T_Money_IncomeList> temp_list(Map<String, Object> params) {
		return incomeDAO.temp_list(params);
	}

	@Override
	@Transactional
	public void temp_save(List<T_Money_IncomeList> temps, T_Sys_User user) {
		if (temps == null || temps.size() == 0) {
			throw new RuntimeException("请选择其他收入");
		}
		List<String> existCode = incomeDAO.temp_check(user.getUs_id(),user.getCompanyid());
		List<T_Money_IncomeList> temps_add = new ArrayList<T_Money_IncomeList>();
		for (T_Money_IncomeList temp : temps) {
			if(!existCode.contains(temp.getIcl_mp_code())){
				temp.setIcl_us_id(user.getUs_id());
				temp.setIcl_remark("");
				temp.setCompanyid(user.getCompanyid());
				temps_add.add(temp);
			}
		}
		if (temps_add.size() > 0) {
			incomeDAO.temp_save(temps_add);
		}
	}

	@Override
	@Transactional
	public void temp_updateMoney(T_Money_IncomeList temp) {
		incomeDAO.temp_updateMoney(temp);
	}

	@Override
	@Transactional
	public void temp_updateRemark(T_Money_IncomeList temp) {
		temp.setIcl_remark(StringUtil.decodeString(temp.getIcl_remark()));
		incomeDAO.temp_updateRemark(temp);
	}

	@Override
	public void temp_del(Integer icl_id) {
		incomeDAO.temp_del(icl_id);
	}

	@Override
	public void temp_clear(Integer us_id, Integer companyid) {
		incomeDAO.temp_clear(us_id, companyid);
	}

	@Override
	public List<T_Money_IncomeList> detail_list(Map<String, Object> params) {
		return incomeDAO.detail_list(params);
	}
	
	@Override
	@Transactional
	public void save(T_Money_Income income, T_Sys_User user) {
		if(income == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		if(StringUtil.isEmpty(income.getIc_shop_code())){
			throw new IllegalArgumentException("店铺名称不能为空");
		}
		if(StringUtil.isEmpty(income.getIc_manager())){
			throw new IllegalArgumentException("经办人不能为空");
		}
		if(StringUtil.isEmpty(income.getIc_ba_code())){
			throw new IllegalArgumentException("银行账户不能为空");
		}
		income.setCompanyid(user.getCompanyid());
		income.setIc_us_id(user.getUs_id());
		income.setIc_maker(user.getUs_name());
		income.setIc_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		income.setIc_sysdate(DateUtil.getCurrentTime());
		//1.查临时表
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("icl_us_id", user.getUs_id());
		params.put("companyid", user.getCompanyid());
		List<T_Money_IncomeList> temps = incomeDAO.temp_list(params);
		if(temps == null || temps.size() == 0){
			throw new RuntimeException("单据已保存，请勿重复提交");
		}
		//2.保存单据
		double ic_money = 0d;
		for (T_Money_IncomeList temp : temps) {
			if(temp.getIcl_money().doubleValue() == 0d){
				throw new RuntimeException("明细数据存在为0的费用类型，请修改");
			}
			ic_money += temp.getIcl_money();
		}
		income.setIc_money(ic_money);
		incomeDAO.save(income, temps);
		//3.删除临时表
		incomeDAO.temp_clear(user.getUs_id(), user.getCompanyid());
	}
	
	@Override
	@Transactional
	public void update(T_Money_Income income, T_Sys_User user) {
		if(income == null){
			throw new IllegalArgumentException("参数不能为null");
		}
		if(StringUtil.isEmpty(income.getIc_shop_code())){
			throw new IllegalArgumentException("店铺名称不能为空");
		}
		if(StringUtil.isEmpty(income.getIc_manager())){
			throw new IllegalArgumentException("经办人不能为空");
		}
		if(StringUtil.isEmpty(income.getIc_ba_code())){
			throw new IllegalArgumentException("银行账户不能为空");
		}
		income.setCompanyid(user.getCompanyid());
		income.setIc_us_id(user.getUs_id());
		income.setIc_maker(user.getUs_name());
		income.setIc_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		income.setIc_sysdate(DateUtil.getCurrentTime());
		//1.查临时表
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("icl_us_id", user.getUs_id());
		params.put("companyid", user.getCompanyid());
		List<T_Money_IncomeList> temps = incomeDAO.temp_list(params);
		if(temps == null || temps.size() == 0){
			throw new RuntimeException("单据已保存，请勿重复提交");
		}
		//1.2验证单据
		T_Money_Income oldIncome = incomeDAO.check(income.getIc_number(), user.getCompanyid());
		if (oldIncome == null || !CommonUtil.AR_STATE_FAIL.equals(oldIncome.getIc_ar_state())) {
			throw new RuntimeException("单据已修改，请勿重复提交");
		}
		//2.保存单据
		double ic_money = 0d;
		for (T_Money_IncomeList temp : temps) {
			if(temp.getIcl_money().doubleValue() == 0d){
				throw new RuntimeException("明细数据存在为0的费用类型，请修改");
			}
			ic_money += temp.getIcl_money();
		}
		income.setIc_money(ic_money);
		incomeDAO.deleteList(income.getIc_number(), user.getCompanyid());
		incomeDAO.update(income, temps);
		//3.删除临时表
		incomeDAO.temp_clear(user.getUs_id(), user.getCompanyid());
	}

	@Override
	@Transactional
	public T_Money_Income approve(String number, T_Approve_Record record, T_Sys_User user) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Money_Income income = incomeDAO.check(number, user.getCompanyid());
		if(income == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(income.getIc_ar_state())){
			throw new RuntimeException("单据已经审核");
		}
		//更新单据审核状态
		income.setIc_ar_state(record.getAr_state());
		income.setIc_ar_date(DateUtil.getCurrentTime());
		incomeDAO.updateApprove(income);
		//保存审核记录表
		record.setAr_number(number);
		record.setAr_sysdate(DateUtil.getCurrentTime());
		record.setAr_us_name(user.getUs_name());
		record.setAr_type("t_money_income");
		record.setCompanyid(user.getCompanyid());
		approveRecordDAO.save(record);
		if(!CommonUtil.AR_STATE_APPROVED.equals(income.getIc_ar_state())){//审核不通过，则直接返回
			return income;
		}
		//3.审核通过:银行账目及流水
		T_Money_Bank bank = bankDAO.queryByCode(income.getIc_ba_code(), user.getCompanyid());
		bank.setBa_balance(bank.getBa_balance()+income.getIc_money());
		bankDAO.updateBalanceById(bank);
		T_Money_BankRun bankRun = new T_Money_BankRun();
		bankRun.setBr_ba_code(income.getIc_ba_code());
		bankRun.setBr_balance(bank.getBa_balance());
		bankRun.setBr_bt_code(CommonUtil.BANKRUN_MONEY_INCOME);
		bankRun.setBr_date(income.getIc_date());
		bankRun.setBr_enter(Math.abs(income.getIc_money()));
		bankRun.setBr_manager(income.getIc_manager());
		bankRun.setBr_number(income.getIc_number());
		bankRun.setBr_remark(income.getIc_remark());
		bankRun.setBr_shop_code(bank.getBa_shop_code());
		bankRun.setBr_sysdate(DateUtil.getCurrentTime());
		bankRun.setCompanyid(user.getCompanyid());
		bankRunDAO.save(bankRun);
		return income;
	}
	
	@Override
	@Transactional
	public T_Money_Income reverse(String number, T_Sys_User user) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Money_Income income = incomeDAO.check(number, user.getCompanyid());
		if(income == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_APPROVED.equals(income.getIc_ar_state())){
			throw new RuntimeException("单据未审核或审核未通过");
		}
		//1.更新单据审核状态
		income.setIc_ar_state(CommonUtil.AR_STATE_NOTAPPROVE);
		income.setIc_ar_date(DateUtil.getCurrentTime());
		incomeDAO.updateApprove(income);
		//2.保存审核记录表
		T_Approve_Record record = new T_Approve_Record();
		record.setAr_state(CommonUtil.AR_STATE_REVERSE_APPROVE);
		record.setAr_describe(user.getUs_name()+"反审核单据");
		record.setAr_number(number);
		record.setAr_sysdate(DateUtil.getCurrentTime());
		record.setAr_us_name(user.getUs_name());
		record.setAr_type("t_money_income");
		record.setCompanyid(user.getCompanyid());
		approveRecordDAO.save(record);
		//3.反审核:银行账目及流水
		T_Money_Bank bank = bankDAO.queryByCode(income.getIc_ba_code(), user.getCompanyid());
		bank.setBa_balance(bank.getBa_balance() - income.getIc_money());
		bankDAO.updateBalanceById(bank);
		T_Money_BankRun bankRun = new T_Money_BankRun();
		bankRun.setBr_ba_code(income.getIc_ba_code());
		bankRun.setBr_balance(bank.getBa_balance());
		bankRun.setBr_bt_code(CommonUtil.BANKRUN_MONEY_INCOME);
		bankRun.setBr_date(income.getIc_date());
		bankRun.setBr_out(Math.abs(income.getIc_money()));
		bankRun.setBr_manager(income.getIc_manager());
		bankRun.setBr_number(income.getIc_number());
		bankRun.setBr_remark("反审核恢复账目");
		bankRun.setBr_shop_code(bank.getBa_shop_code());
		bankRun.setBr_sysdate(DateUtil.getCurrentTime());
		bankRun.setCompanyid(user.getCompanyid());
		bankRunDAO.save(bankRun);
		return income;
	}
	
	@Override
	@Transactional
	public void initUpdate(String number, Integer us_id, Integer companyid) {
		List<T_Money_IncomeList> details = incomeDAO.detail_list_forsavetemp(number, companyid);;
		for(T_Money_IncomeList item:details){
			item.setIcl_us_id(us_id);
		}
		incomeDAO.temp_clear(us_id, companyid);
		incomeDAO.temp_save(details);
	}
	
	@Override
	@Transactional
	public void del(String number, Integer companyid) {
		if (number == null) {
			throw new IllegalArgumentException("参数number不能为null");
		}
		T_Money_Income income = incomeDAO.check(number, companyid);
		if(income == null){
			throw new RuntimeException("单据不存在");
		}
		if(!CommonUtil.AR_STATE_NOTAPPROVE.equals(income.getIc_ar_state()) && !CommonUtil.AR_STATE_FAIL.equals(income.getIc_ar_state())){
			throw new RuntimeException("单据已审核通过不能删除！");
		}
		incomeDAO.del(number, companyid);
	}
	
	@Override
	public Map<String, Object> loadPrintData(String number, Integer sp_id, T_Sys_User user) {
		Map<String, Object> resultMap = printDAO.loadPrint4Bill(sp_id);
		T_Money_Income income = incomeDAO.load(number, user.getCompanyid());
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("icl_number", number);
		params.put("companyid", user.getCompanyid());
		List<T_Money_IncomeList> incomeList = incomeDAO.detail_list(params);
		resultMap.put("income", income);
		resultMap.put("incomeList", incomeList);
		resultMap.put("shop", shopDAO.load(income.getIc_shop_code(), user.getCompanyid()));
		return resultMap;
	}
	
	@Override
	public List<IncomeReportDto> listReport(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		return incomeDAO.listReport(params);
	}
	
	@Override
	public List<T_Money_IncomeList> listReportDetail(Map<String, Object> params) {
		Object companyid = params.get(CommonUtil.COMPANYID);
		if (companyid == null) {
			throw new IllegalArgumentException("连接超时，请重新登录!");
		}
		return incomeDAO.listReportDetail(params);
	}
	
}
